﻿
using System;
using System.ComponentModel.DataAnnotations.Schema;
using System.Reflection;
using System.Threading.Tasks;

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;

namespace Jack.EntityFrameworkCore.ConsoleTest.Entities
{
    public class DemoDbContext : JackDbContext<DemoDbContext>
    {
        public DemoDbContext()
        {
        }

        public DemoDbContext(DbContextOptions<DemoDbContext> options) : base(options)
        {
        }

        private string currentTenantId;
        public void SetTenantId(string newTenantId)
        {
            // 更新当前租户 ID
            currentTenantId = newTenantId;
        }


        // 2. 在 DbContext 中重写 OnModelCreating 方法，并使用 Fluent API 设置表名
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //modelBuilder.Entity<UserModel>().ToTable(GetTenantTableName<UserModel>(currentTenantId));
            //modelBuilder.Entity<UserModel>().ToTable("user");

            base.OnModelCreating(modelBuilder);

            //foreach (IMutableEntityType entity in modelBuilder.Model.GetEntityTypes())
            //{
            //    entity.SetSchema("MySchema");
            //    entity.SetTableName(GetTenantTableName(currentTenantId, entity));
            //}
        }

        // 假设要动态更改的实体是 Tenant，将表名设置为 "{tenantId}_{tableName}"
        // 其中 {tenantId} 表示当前租户的 ID
        // 1. 定义动态表名的函数
        public static string GetTenantTableName<TEntity>(string tenantId)
            where TEntity : IBaseModel
        {
            Type entityType = typeof(TEntity);
            string tableName = entityType.Name;
            if (entityType.IsDefined(typeof(TableAttribute), true))
            {
                var tableAttribute = entityType.GetCustomAttribute<TableAttribute>(true);
                tableName = tableAttribute.Name;
            }

            return $"{tenantId}_{tableName}";
        }

        public static string GetTenantTableName(string tenantId, IMutableEntityType entity)
        {
            string tableName = entity.GetTableName();
            return $"{tenantId}_{tableName}";
        }

        // 3. 在运行时更改表名
        public void TestChangeTable<TEntity>()
            where TEntity : class, IBaseModel
        {
            // 构造新的表名，并将其应用到实体
            //var newTableName = GetTenantTableName<TEntity>(currentTenantId);
            //var entityType = this.Model.FindEntityType(typeof(TEntity));
            //var mutableEntityType = entityType as IMutableEntityType;
            //IConventionEntityType conventionEntityType = entityType as IConventionEntityType;
            //var tableName = entityType.GetTableName();
            //mutableEntityType.RemoveAnnotation(newTableName);
            //mutableEntityType.Model.GetRelationalModel()

            var sql = this.Set<TEntity>().ToSql();
            Console.WriteLine(sql);

            //try
            //{
            //    conventionEntityType.SetTableName(newTableName);
            //}
            //catch (Exception ex)
            //{
            //    Console.WriteLine(ex);
            //}

            //IAnnotation annotation = mutableEntityType.GetAnnotation("Relational:TableName");
            //IConventionAnnotation conventionAnnotation = annotation as IConventionAnnotation;
            //var configurationSource = conventionAnnotation.GetConfigurationSource();

            //mutableEntityType.SetTableName(newTableName);
            //mutableEntityType.RemoveAnnotation("Relational:TableName");
            //mutableEntityType.SetAnnotation("Relational:TableName", newTableName);

            //mutableEntityType.Relational().TableName = "";

            sql = this.Set<TEntity>().ToSql();
            Console.WriteLine(sql);
        }
    }
}
